package com.njust.RateMyTray_backend.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.njust.RateMyTray_backend.common.CustomException;
import com.njust.RateMyTray_backend.common.ForbiddenException;
import com.njust.RateMyTray_backend.common.ResourceNotFoundException;
import com.njust.RateMyTray_backend.dto.CommentCreateDTO;
import com.njust.RateMyTray_backend.dto.ReplyCreateDTO;
import com.njust.RateMyTray_backend.entity.Comment;
import com.njust.RateMyTray_backend.entity.CommentLike;
import com.njust.RateMyTray_backend.entity.Dish;
import com.njust.RateMyTray_backend.entity.Notification;
import com.njust.RateMyTray_backend.entity.Window;
import com.njust.RateMyTray_backend.mapper.CommentMapper;
import com.njust.RateMyTray_backend.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;

@Slf4j
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Lazy // 添加 @Lazy 注解来打破循环依赖
    @Autowired
    private DishService dishService;

    @Autowired
    private WindowService windowService;

    @Autowired
    private CommentLikeService commentLikeService;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private ValidationService validationService;
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Comment createComment(Long userId, CommentCreateDTO createDTO) {
        // 1. 验证评价对象是否存在
        validationService.validateTargetExists(createDTO.getTargetType(), createDTO.getTargetId());
        
        Comment comment = new Comment();
        comment.setReviewerId(userId);
        comment.setTargetType(createDTO.getTargetType());
        comment.setTargetId(createDTO.getTargetId());
        comment.setRating(createDTO.getRating());
        comment.setContent(createDTO.getContent());
        comment.setIsAnonymous(createDTO.getIsAnonymous());
        
        // 2. 序列化图片URL列表
        if (!CollectionUtils.isEmpty(createDTO.getImageUrls())) {
            try {
                comment.setImageUrls(objectMapper.writeValueAsString(createDTO.getImageUrls()));
            } catch (JsonProcessingException e) {
                log.error("序列化评论图片URL列表失败: {}", createDTO.getImageUrls(), e);
                // 根据业务需求，这里可以抛出异常或仅记录日志
            }
        }
        
        // 3. 设置默认值
        comment.setStatus("pending"); // 默认待审核
        comment.setCommentedAt(LocalDateTime.now());
        comment.setHelpfulCount(0);
        comment.setIsOfficialReply(false);
        
        this.save(comment);
        
        return comment;
    }

    @Transactional
    @Override
    public int likeComment(Long userId, Long commentId) {
        // 1. 检查评价是否存在
        Comment comment = this.getById(commentId);
        if (comment == null) {
            throw new ResourceNotFoundException("评价不存在");
        }

        // 2. 检查是否已点赞
        long count = commentLikeService.lambdaQuery()
                .eq(CommentLike::getUserId, userId)
                .eq(CommentLike::getCommentId, commentId)
                .count();
        if (count > 0) {
            throw new CustomException("您已点赞过此评论");
        }

        // 3. 添加点赞记录
        commentLikeService.save(new CommentLike(userId, commentId));
        
        // 4. 更新评价表中的点赞数
        comment.setHelpfulCount(comment.getHelpfulCount() + 1);
        this.updateById(comment);
        
        // 5. 创建通知
        // 只有当不是自己给自己点赞时才创建通知
        if (!comment.getReviewerId().equals(userId)) {
            String content = String.format("您的评论 '%.20s...' 收到了一个赞。", comment.getContent());
            Notification notification = new Notification();
            notification.setUserId(comment.getReviewerId());
            notification.setType("commentLiked");
            notification.setContent(content);
            notification.setSourceId(commentId);
            notification.setIsRead(false);
            notification.setCreatedAt(LocalDateTime.now());
            notificationService.save(notification);
        }
        
        return comment.getHelpfulCount();
    }

    @Override
    public void replyToComment(Long userId, Long parentCommentId, ReplyCreateDTO replyDTO) {
        // 1. 验证父评论是否存在
        Comment parentComment = this.getById(parentCommentId);
        if (parentComment == null) {
            throw new ResourceNotFoundException("被回复的评论不存在");
        }
        
        // 2. 创建回复评论（移除权限验证，允许所有用户回复）
        Comment reply = new Comment();
        reply.setParentId(parentCommentId);
        reply.setReviewerId(userId); // 回复者是当前用户
        reply.setTargetId(parentComment.getTargetId());
        reply.setTargetType(parentComment.getTargetType());
        reply.setContent(replyDTO.getReplyContent());
        reply.setIsOfficialReply(false); // 不再标记为官方回复
        reply.setRating(0); // 回复通常不带评分
        reply.setIsAnonymous(false); // 回复不匿名
        reply.setCommentedAt(LocalDateTime.now());
        reply.setStatus("approved"); // 回复默认审核通过
        reply.setHelpfulCount(0);
        
        this.save(reply);
        
        // 3. 创建通知（只有当不是自己回复自己时才创建通知）
        if (!parentComment.getReviewerId().equals(userId)) {
            String content = String.format("有用户回复了您的评论 '%.20s...'", parentComment.getContent());
            Notification notification = new Notification();
            notification.setUserId(parentComment.getReviewerId());
            notification.setType("merchantReply");
            notification.setContent(content);
            notification.setSourceId(parentCommentId);
            notification.setIsRead(false);
            notification.setCreatedAt(LocalDateTime.now());
            notificationService.save(notification);
        }
    }


} 